<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    // 块不是作用域：var对所在作用域内前后的代码均起作用
    function test(a, b) {
        var t = a;
        function test2() {
            // 先引用后var（只声明未定义）值为undefined；
            // console.log(t); // undefined;
            if (b > 0) {
                var t = b;
            }
        }
        test2();
    }
    test(1, 2);

    // 在循环内过度共享变量：循环与定时器用时不一致
    function test3() {
        var message = ["message1", "message2", "message3"];
        for (var i = 0, length = message.length; i < length; i++) {
            setTimeout(function () {
                // 3 undefined
                console.log(i, message[i]); // 当循环结束后i都变成了3（不管定时器定时time多少，遍历输出都是最后一个数）
            }, 0);
        }
    }
    test3();
    /*let关键字区别：
    1，以代码块为作用域
    2，声明的全局变量不是全局对象（window）的属性
    3，声明的全局作用域是包含web页面所有js代码的隐式代码块
    4，在for系列中使用如for(let x...)形式，每一次循环会新建一个变量x（闭包），不是共享变量
    5，在闭包中，js引擎会进行一次初始化检查，意味着let声明的变量比var慢一些
    6，声明之前使用let声明的变量引发错误（未初始化）
    7，未初始化的变量处于临时死亡区中
    8，重声明使用let声明的变量导致语法错误
    9，企图将所有var声明的变量修改成let也会引发一些错误（见3，8）（模块机制除外）
    10，let是严格模式保留字，在非严格模式下可以使用var let；但不能使用let let；*/
    // 1
    function let1() {
        if (1) {
            var b = 10;
            let a = 20;
        }
        console.log(b); // 10
        console.log(a); //  ReferenceError: a is not defined
    }
    // let1();
    // 2
    var global_var = "global var";
    let global_let = "global let";
    console.log(window.global_var, window.global_let); // global var undefined
    // 4
    function test4() {
        let message = ["message1", "message2", "message3"];
        for (let i = 0, length = message.length; i < length; i++) {
            setTimeout(function () {
                console.log(i, message[i]); // 1,message1, 2,.. 3...
            }, 1000);
        }
    }
    test4();
    // 6
    function let6() {
        console.log(referenceBeforeUseVar); // undefined
        console.log(referenceBeforeUseLet); // ReferenceError: Cannot access(访问) 'referenceBeforeUseLet' before initialization
        var referenceBeforeUseVar = "reference before use var";
        let referenceBeforeUseLet = "reference before use let";
    }
    // let6();
    // 8
    function let8() {
        var origin_var = "origin var";
        var origin_var = "now var";
        console.log(origin_var);
       /* let origin_let = "origin let";
        let origin_let = "now let";*/
        console.log(origin_let); // SyntaxError: Identifier 'origin_let' has already been declared
    }
    // let8();

</script>
<script type="text/javascript">
    // 3
    var global_var = "global var";
    console.log(global_var);

    let global_let = "global let"; //  SyntaxError: Identifier 'global_let' has already been declared
    console.log(global_let);
</script>
</body>
</html>